package net.entelijan.cobean.tree;

import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import net.entelijan.cobean.core.IInitializer;
import net.entelijan.cobean.core.ISingleSelectionCobean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DefaultTreeInitializer extends AbstractTreeInitializer implements
		IInitializer<ISingleSelectionCobean<Object>> {

	private static Log log = LogFactory.getLog(DefaultTreeInitializer.class);

	private ITreeLevelDescription treeLevelDescription;

	public DefaultTreeInitializer() {
		super();
	}

	@Override
	public ISingleSelectionCobean<Object> initialize() {
		commonInit();

		return new ISingleSelectionCobean<Object>() {

			private Object value;

			private TreeState treeState = new TreeState();

			private Object selectedValue;

			@Override
			public Object getSelectedValue() {
				Object re = null;
				if (selectedValue != null) {
					re = ((CobeanTreeNode) selectedValue).getModel();
				}
				return re;
			}

			@Override
			public void setSelectedValue(Object selectedValue) {
				log.info("[setSelectedValue] value='" + selectedValue + "'");
				TreePath selectionPath = createTreePath(selectedValue);
				coTree.setSelectionPath(selectionPath);
				coTree.scrollPathToVisible(selectionPath);
			}

			@Override
			public Object getValue() {
				return this.value;
			}

			@Override
			public void setValue(Object value) {
				this.value = value;
				TreeModel treeModel = createTreeModel(value,
						treeLevelDescription);
				coTree.setCellRenderer(new CobeanTreeCellRenderer());
				treeState.restore(treeModel);
				treeModel.addTreeModelListener(treeState);
				coTree.setModel(treeModel);
				coTree.getSelectionModel().setSelectionMode(
						TreeSelectionModel.SINGLE_TREE_SELECTION);
				coTree.addTreeSelectionListener(new TreeSelectionListener() {

					@Override
					public void valueChanged(TreeSelectionEvent e) {
						TreePath path = e.getPath();
						selectedValue = (Object) path.getLastPathComponent();
					}

				});
			}

		};
	}

	public ITreeLevelDescription getTreeLevelDescription() {
		return treeLevelDescription;
	}

	public void setTreeLevelDescription(
			ITreeLevelDescription treeLevelDescription) {
		this.treeLevelDescription = treeLevelDescription;
	}

}
